import java.util.ArrayList;
import java.util.Random;

public class ActiveOrder implements StockValueObserver, Comparable<Object> {

	public int activeOrderId;
	public AbstractOrder order;
	private static boolean toggle = false;

	public int getActiveOrderId() {
		return activeOrderId;
	}

	public void setActiveOrderId(int activeOrderId) {
		this.activeOrderId = activeOrderId;
	}

	public AbstractOrder getOrder() {
		return order;
	}

	public void setOrder(AbstractOrder order) {
		this.order = order;
	}

	@Override
	public void updateOrder(StockValueObserver buyer,
			StockValueObserver seller, int matchedQuantity) {

		System.out.println("deleting Matched Active Orders after Match: ");
		if (!toggle) {
			ActiveOrderRepository.getOrderRepository().removeActiveOrder(
					((ActiveOrder) buyer).activeOrderId);
			removeOrdersFromQueue(buyer);
			toggle = true;
		} else {
			toggle = false;
			ActiveOrderRepository.getOrderRepository().removeActiveOrder(
					((ActiveOrder) seller).activeOrderId);
			removeOrdersFromQueue(seller);
		}
	}

	public void retrieveOrdersFromRepository() {
		OrderRepository orderRepository = OrderRepository.getOrderRepository();
		ArrayList<AbstractOrder> orders = orderRepository
				.getInitializedOrders();

		Random random = new Random();
		QueueRepository queueRepository = QueueRepository.getOrderRepository();

		ActiveOrderRepository activeOrderRepository = ActiveOrderRepository
				.getOrderRepository();
		for (AbstractOrder order : orders) {
			ActiveOrder activeOrder = new ActiveOrder();
			activeOrder.activeOrderId = order.getOrderId()
					+ (random.nextInt(1000) + 1);
			activeOrder.order = order;
			order.activeOrder();
			activeOrderRepository.addActiveOrder(activeOrder);

			if (order instanceof StockOrder) {
				int stockId = ((StockOrder) order).getStockId();
				Queue queue = queueRepository.getQueue(stockId);
				if (((StockOrder) order).getOrderType().equals(OrderType.LIMIT)) {
					queue.add(activeOrder);
				} else if (((StockOrder) order).getOrderType().equals(
						OrderType.MARKET)) {
					queue.addInMarketQueue(activeOrder);
				}
			} else {
				ProcessMutualFund.mutualFundOrderList
						.add((MutualFundOrder) order);
			}
		}
	}

	public static void performOperationsOnMarketClose() {
		ProcessMutualFund.processMutualFundOrders();
		ActiveOrderRepository.getOrderRepository().deleteExpiredOrders();
		ActiveOrderRepository.getOrderRepository().deleteMutualFundOrders();
	}

	public int compareTo(Object o) {
		if (this.order.getPriceLimit() < ((ActiveOrder) o).getOrder()
				.getPriceLimit())
			return -1;
		if (this.order.getPriceLimit() > ((ActiveOrder) o).getOrder()
				.getPriceLimit())
			return 1;
		else
			return 0;

	}

	public boolean removeOrdersFromQueue(StockValueObserver observer) {

		ActiveOrder obs = (ActiveOrder) observer;
		QueueRepository queueRepository = QueueRepository.getOrderRepository();

		if (obs.order.getOrderType().equals(OrderType.MARKET)) {
			Queue q = queueRepository.getQueue(obs.order.getStockId());

			for (int i = 0; i < q.getMarketQueue().size(); i++) {
				ActiveOrder activeOrder = q.getMarketQueue().get(i);
				if (activeOrder.getActiveOrderId() == obs.getActiveOrderId()) {
					q.getMarketQueue().remove(i);
					return true;
				}
			}

		} else if (obs.order.getOrderType().equals(OrderType.LIMIT)) {
			Queue q = queueRepository.getQueue(obs.order.getStockId());

			if (obs.order.getOrderCategory().equals(OrderCategory.BUY)) {
				for (int i = 0; i < q.getBuyQueue().size(); i++) {
					ActiveOrder activeOrder = q.getBuyQueue().get(i);
					if (activeOrder.getActiveOrderId() == obs
							.getActiveOrderId()) {
						q.getBuyQueue().remove(i);
						return true;
					}
				}
			} else if (obs.order.getOrderCategory().equals(OrderCategory.SELL)) {
				for (int i = 0; i < q.getSellQueue().size(); i++) {
					ActiveOrder activeOrder = q.getSellQueue().get(i);
					if (activeOrder.getActiveOrderId() == obs
							.getActiveOrderId()) {
						q.getSellQueue().remove(i);
						return true;
					}
				}
			}
		}
		return false;
	}
}
